package com.cxs.shopstore.es;

import com.cxs.shopstore.config.ESProperties;
import com.cxs.shopstore.models.Good;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

/*
 * @Author:cxs
 * @Date:2021/5/3  10:05
 * @Version 1.0
 * */
@SuppressWarnings("all")
@Slf4j
@Component
public class ESTemplete {
    private static final String INDEX = "shop_goods";
    private final RestHighLevelClient client;
    @Autowired
    private ESProperties esProp;
    @Autowired
    private ObjectMapper objectMapper;

    public ESTemplete(@Autowired ESProperties esProperties) {
        client = new RestHighLevelClient(
                RestClient.builder(new HttpHost(esProperties.getHost(),esProperties.getPort()))
        );
    }

    public String getIndex(){
        return INDEX;
    }
    //获得ES连接
    public RestHighLevelClient getRestHighLevelClient(){
        return new RestHighLevelClient(
                RestClient.builder(new HttpHost(esProp.getHost(),esProp.getPort()))
        );
    }

    //批量添加数据
    public void bluksave(List<ESgoodsDoc> list) throws IOException {
        BulkRequest request = new BulkRequest();
        for (int i = 0; i < list.size(); i++) {
            request.add(new IndexRequest(
                    getIndex()).id(list.get(i).getId())
                    .source(objectMapper.writeValueAsString(list.get(i)), XContentType.JSON)
            );
        }
        client.bulk(request, RequestOptions.DEFAULT);
    }
    //删除es中指定的数据
    public void deleteByid(String id){
        DeleteRequest request = new DeleteRequest(getIndex());
        request.id(id);
        try {
            client.delete(request,RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("",e);
        }
    }
    //删除所有数据
    public void deleteall(){
        DeleteByQueryRequest request = new DeleteByQueryRequest(getIndex());
        request.setQuery(QueryBuilders.matchAllQuery());
        try {
            client.deleteByQuery(request,RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("",e);
        }
    }

    //处理数据
    public List<ESgoodsDoc> changeList(List<Good> goods){
        List<ESgoodsDoc> list = new ArrayList<>();
        for (Good good : goods) {
            ESgoodsDoc doc = new ESgoodsDoc();
            doc.setId(UUID.randomUUID().toString().replace("-",""));
            doc.setName(good.getGoodName());
            doc.setPrice(good.getGoodPrice());
            doc.setImgPath(good.getGoodImgPath());
            doc.setCreateTime(good.getGoodCreateTime());
            doc.setSku(good.getGoodSku());
            doc.setSaler(good.getGoodSaler());
            list.add(doc);
        }
        return list;
    }
    //转换map为list
    public List<Good> mapchangeList(List<Map<String, Object>> mapList){
        List<Good> list = new ArrayList<>();
        for (Map<String, Object> goodmap : mapList) {
            Good good = new Good();
            good.setGoodId(UUID.randomUUID().toString().replace("-",""));
            good.setGoodName(goodmap.get("name").toString());
            good.setGoodPrice(goodmap.get("price").toString());
            good.setGoodImgPath(goodmap.get("imgPath").toString());
            good.setGoodSaler(goodmap.get("saler").toString());
            good.setGoodCreateTime(Long.parseLong(goodmap.get("createTime").toString()));
            good.setGoodSku(Long.parseLong(goodmap.get("sku").toString()));
            list.add(good);
        }
        return list;
    }

    //高亮查询
    public List<Map<String,Object>> highlightSearch(String keyword,int start,int pageSize){
        List<Map<String,Object>> listmap = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        //查询请求
        SearchRequest request = new SearchRequest(getIndex());
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //分页
        builder.from(start);
        builder.size(pageSize);
        builder.query(QueryBuilders.matchQuery("name",keyword));
        //高亮字段封装
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<span className='title' style='color:red'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.field("name");
        builder.highlighter(highlightBuilder);
        request.source(builder);
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            for (SearchHit hit : response.getHits().getHits()) {
                map = hit.getSourceAsMap();
                //获取高亮搜索结果
                HighlightField highlightField = hit.getHighlightFields().get("name");
                //将数据打造为String类型
                if(highlightField != null){
                    Text[] fragments = highlightField.fragments();
                    String heighName = "";
                    for (Text fragment : fragments) {
                        heighName +=fragment;
                    }
                    map.put("name",heighName);
                }
                listmap.add(map);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return listmap;
    }

    //高亮查询
    public List<Good> highlightSearch(String keyword){
        List<Good> list = new ArrayList<>();
        List<Map<String,Object>> listmap = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        //查询请求
        SearchRequest request = new SearchRequest(getIndex());
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //分页
        builder.size(30);
        builder.query(QueryBuilders.matchQuery("name",keyword));
        //高亮字段封装
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.requireFieldMatch(false);
        highlightBuilder.preTags("<span className='title' style='color:red'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.field("name");
        builder.highlighter(highlightBuilder);
        request.source(builder);
        try {
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            for (SearchHit hit : response.getHits().getHits()) {
                map = hit.getSourceAsMap();
                //获取高亮搜索结果
                HighlightField highlightField = hit.getHighlightFields().get("name");
                //将数据打造为String类型
                if(highlightField != null){
                    Text[] fragments = highlightField.fragments();
                    String heighName = "";
                    for (Text fragment : fragments) {
                        heighName +=fragment;
                    }
                    map.put("name",heighName);
                }
                listmap.add(map);
            }
            list =  mapchangeList(listmap);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
    //判断是否存在
    public boolean existBySku(Long sku){
        SearchResponse response = null;
        SearchRequest request = new SearchRequest(getIndex());
        request.source(
                new SearchSourceBuilder().query(QueryBuilders.termQuery("sku",sku))
        );
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            if(hit.getSourceAsMap() != null){
                return true;
            }else{
                return false;
            }
        }
        return false;
    }
    //按照关键字查询
    public List<Map<String, Object>> selectByKeyword(String keyword){
        SearchResponse response = null;
        List<Map<String,Object>> listmap = new ArrayList<>();
        SearchRequest request = new SearchRequest(getIndex());
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.size(30);
        builder.query(QueryBuilders.matchQuery("name",keyword));
        request.source(builder);
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("",e);
            e.printStackTrace();
        }
        if(response != null){
            for (SearchHit hit : response.getHits().getHits()) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                listmap.add(sourceAsMap);
            }
        }
        return listmap;
    }
    //查询所有
    public List<Good> matchall(){
        SearchResponse response = null;
        List<Good> list = new ArrayList<>();
        List<Map<String,Object>> listmap = new ArrayList<>();
        SearchRequest request = new SearchRequest(getIndex());
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.size(100);
        builder.query(QueryBuilders.matchAllQuery());
        request.source(builder);
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("",e);
            e.printStackTrace();
        }
        if(response != null){
            for (SearchHit hit : response.getHits().getHits()) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                listmap.add(sourceAsMap);
            }
            list = mapchangeList(listmap);
        }
        return list;
    }
}
